/**
 * @file remoteTask.c
 * @brief 遥控器接受与发送的任务（没有写在DMA）
 * @author TuxMonkey (nqx2004@gmail.com)
 * @version 1.0
 * @date 2024-09-21
 *
 * @copyright Copyright (c) 2024 DLMU-C.ONE
 *
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2024-09-21 <td>1.0     <td>TuxMonkey     <td>内容
 * </table>
 */

#include "cmsis_os.h"
#include "tim.h"
#include "delayticks.h"
#include "remoteTask.h"
#include "string.h"
#include "usart.h"

// 定义SBUS协议的起始标志
#define SBUS_HEAD 0X0F

// 定义SBUS协议的结束标志
#define SBUS_END 0X00

// 定义接收缓冲区，用于存储接收到的数据
uint8_t rx_buff[BUFF_SIZE];

// 定义遥控器对象，用于控制与遥控器相关的操作
remoter_t remoter;

// 用于控制遥控器状态和标志位
rc_ctrl_t rc_ctrl;

/**
 * @brief 解析SBUS帧数据
 *
 * 本函数用于解析来自SBUS遥控器的帧数据。SBUS是一种用于遥控模型的通信协议。
 * 函数首先检查数据包是否以SBUS头部和尾部特定的字节开始和结束，以确保数据包的完整性。
 * 如果数据包不符合预期的格式，函数将立即返回，不进行进一步处理。
 *
 * 对于特定的控制信号，比如当接收到0x0C时，标记遥控器为离线状态，其他情况下则为在线状态。
 * 随后，函数解析数据包中的通道信号。SBUS协议支持多个通道，每个通道对应遥控器的一个控制输入。
 * 这些通道的数值被解码并存储在remoter结构体的rc.ch数组中，供后续使用。
 *
 * 最后，函数维护四个静态变量来记录开关位置的最后状态，这在调试过程中用于跟踪用户输入的变化。
 *
 * @param remoter 指向remoter_t结构体的指针，用于存储解析后的遥控器数据
 * @param rc_ctrl 指向rc_ctrl_t结构体的指针，用于存储解析后的遥控器数据
 * @param buf 指向接收到的数据包的指针
 */
void sbus_frame_parse(remoter_t *remoter, rc_ctrl_t *rc_ctrl, uint8_t *buf)
{
	if ((buf[0] != SBUS_HEAD) || (buf[24] != SBUS_END))
		return;

	if (buf[23] == 0x0C)
		remoter->online = 0;
	else
		remoter->online = 1;

	remoter->rc.ch[0] = ((buf[1] | buf[2] << 8) & 0x07FF);					   // 通道1 (云台yaw)
	remoter->rc.ch[1] = ((buf[2] >> 3 | buf[3] << 5) & 0x07FF);				   // 通道2 (云台pitch)
	remoter->rc.ch[2] = ((buf[3] >> 6 | buf[4] << 2 | buf[5] << 10) & 0x07FF); // 通道3 (前后)
	remoter->rc.ch[3] = ((buf[5] >> 1 | buf[6] << 7) & 0x07FF);				   // 通道4 (左右)
	remoter->rc.ch[4] = ((buf[6] >> 4 | buf[7] << 4) & 0x07FF);				   // 通道5 (SWA)
	remoter->rc.ch[5] = ((buf[7] >> 7 | buf[8] << 1 | buf[9] << 9) & 0x07FF);  // 通道6 (SWB)
	remoter->rc.ch[6] = ((buf[9] >> 2 | buf[10] << 6) & 0x07FF);			   // 通道7 (SWC)
	remoter->rc.ch[7] = ((buf[10] >> 5 | buf[11] << 3) & 0x07FF);			   // 通道8 (SWD)
	remoter->rc.ch[8] = ((buf[12] | buf[13] << 8) & 0x07FF);				   // 通道9 (VrA旋钮)
	remoter->rc.ch[9] = ((buf[13] >> 3 | buf[14] << 5) & 0x07FF);			   // 通道10 (VrB旋钮)
	//!!!调试时选择remoter放在Watch窗口进行调试!!!记得在remoter上右键选择十进制显示要不然怪怪的
	//以及调试时不要忘记点选view里的实时刷新 要不然watch的变量不会刷新

	// static uint8_t sw_left1_last = RC_SW_DOWN;	// SWA 摩擦轮
	// static uint8_t sw_left2_last = RC_SW_DOWN;	// SWB 自瞄
	// static uint8_t sw_right1_last = RC_SW_MID;	// SWC 原模式切换
	// static uint8_t sw_right2_last = RC_SW_DOWN; // SWD 弹仓盖

	// 解析开关状态
	
	// 根据遥控器通道4的值，更新遥控器控制结构体中的sw_a字段
	// 如果通道4的值为0x00F0，表示SWA按钮被按下，将sw_a设置为RC_SW_UP
	// 否则，将sw_a设置为RC_SW_DOWN，表示SWA按钮未被按下 除了C同理
	rc_ctrl->sw_a = (remoter->rc.ch[4] == 0x00F0) ? RC_SW_UP : RC_SW_DOWN;
	rc_ctrl->sw_b = (remoter->rc.ch[5] == 0x00F0) ? RC_SW_UP : RC_SW_DOWN;
	rc_ctrl->sw_c = remoter->rc.ch[6];									   // SWC
	rc_ctrl->sw_d = (remoter->rc.ch[7] == 0x00F0) ? RC_SW_UP : RC_SW_DOWN; // SWD

	// 解析SWC状态
	if (remoter->rc.ch[6] == 0x00F0)
	{
		rc_ctrl->sw_c = RC_SW_UP;
	}
	else if (remoter->rc.ch[6] == 0x0400)
	{
		rc_ctrl->sw_c = RC_SW_MID;
	}
	else if (remoter->rc.ch[6] == 0x070F)
	{
		rc_ctrl->sw_c = RC_SW_DOWN;
	}
	else
	{
		rc_ctrl->sw_c = 0; // 未知状态
	}

	// SWC的状态变化
	if (rc_ctrl->sw_c != rc_ctrl->sw_c_last)
	{
		if (rc_ctrl->sw_c == RC_SW_UP)
		{
			rc_ctrl->sw_c_midtoup_flag = 1;
			rc_ctrl->sw_c_uptomid_flag = 0;
			rc_ctrl->sw_c_midtodown_flag = 0;
		}
		else if (rc_ctrl->sw_c == RC_SW_MID)
		{
			rc_ctrl->sw_c_midtoup_flag = 0;
			rc_ctrl->sw_c_uptomid_flag = 1;
			rc_ctrl->sw_c_midtodown_flag = 0;
		}
		else if (rc_ctrl->sw_c == RC_SW_DOWN)
		{
			rc_ctrl->sw_c_midtoup_flag = 0;
			rc_ctrl->sw_c_uptomid_flag = 0;
			rc_ctrl->sw_c_midtodown_flag = 1;
		}
	}
	rc_ctrl->sw_c_last = rc_ctrl->sw_c;

	// SWA和SWB的状态变化
	if (rc_ctrl->sw_a != rc_ctrl->sw_a_last)
	{
		rc_ctrl->sw_a_up_to_down_flag = (rc_ctrl->sw_a == RC_SW_UP) ? 1 : 0;
	}
	rc_ctrl->sw_a_last = rc_ctrl->sw_a;

	if (rc_ctrl->sw_b != rc_ctrl->sw_b_last)
	{
		rc_ctrl->sw_b_up_to_down_flag = (rc_ctrl->sw_b == RC_SW_UP) ? 1 : 0;
	}
	rc_ctrl->sw_b_last = rc_ctrl->sw_b;

	// SWD的状态变化
	if (rc_ctrl->sw_d != rc_ctrl->sw_d_last)
	{
		rc_ctrl->sw_d_up_to_down_flag = (rc_ctrl->sw_d == RC_SW_UP) ? 1 : 0;
	}
	rc_ctrl->sw_d_last = rc_ctrl->sw_d;
	// ！！！调试时使用rc_ctrl加到Watch窗口进行调试！！！

	rc_ctrl->ch1 = remoter->rc.ch[0]-1024;// 减去1024，使遥控器中轴为0
	rc_ctrl->ch2 = remoter->rc.ch[1]-1024;// 减去1024，使遥控器中轴为0
	rc_ctrl->ch3 = remoter->rc.ch[2]-1024;// 减去1024，使遥控器中轴为0
	rc_ctrl->ch4 = remoter->rc.ch[3]-1024;// 减去1024，使遥控器中轴为0
	
	// if(rc_ctrl->sw_left!=sw_left_last)
	// {
	// 	if((sw_left_last==RC_SW_MID)&&(rc_ctrl->sw_left==RC_SW_UP)){rc_ctrl->sw_left_midtoup_flag=1;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=0;}
	// 	else if((sw_left_last==RC_SW_UP)&&(rc_ctrl->sw_left==RC_SW_MID)){rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=1;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=0;}
	// 	else if((sw_left_last==RC_SW_MID)&&(rc_ctrl->sw_left==RC_SW_DOWN)){rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=1;rc_ctrl->sw_left_downtomid_flag=0;}
	// 	else if((sw_left_last==RC_SW_DOWN)&&(rc_ctrl->sw_left==RC_SW_MID)){rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=1;}
	// 	else {rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=0;}
	// }
	// else {rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=0;}

	// if(rc_ctrl->sw_right!=sw_right_last)
	// {
	// 	if((sw_right_last==RC_SW_MID)&&(rc_ctrl->sw_right==RC_SW_UP)){rc_ctrl->sw_right_midtoup_flag=1;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=0;}
	// 	else if((sw_right_last==RC_SW_UP)&&(rc_ctrl->sw_right==RC_SW_MID)){rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=1;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=0;}
	// 	else if((sw_right_last==RC_SW_MID)&&(rc_ctrl->sw_right==RC_SW_DOWN)){rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=1;rc_ctrl->sw_right_downtomid_flag=0;}
	// 	else if((sw_right_last==RC_SW_DOWN)&&(rc_ctrl->sw_right==RC_SW_MID)){rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=1;}
	// 	else {rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=0;}
	// }
	// else {rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=0;}

	// sw_left_last = rc_ctrl->sw_left;
	// sw_right_last = rc_ctrl->sw_right;
}

/***********************************************************************
** 函 数 名： dbus_to_rc()
** 函数说明： 遥控器DBUS协议解析(在UART3中断调用)
**---------------------------------------------------------------------
** 输入参数： DBUS数据包地址,遥控器及键鼠指令变量地址
** 返回参数： 无
***********************************************************************/
// void dbus_to_rc(uint8_t *dbus_buf, RC_ctrl_t *rc_ctrl)
//{
//	static uint8_t sw_left_last = RC_SW_MID;
//	static uint8_t sw_right_last = RC_SW_DOWN;
//
//	if((dbus_buf==NULL)||(rc_ctrl==NULL)){ return;}
//
//	rc_ctrl->recv_cnt++;

//	rc_ctrl->ch1 = (dbus_buf[0] | (dbus_buf[1] << 8)) & 0x07ff;
//	rc_ctrl->ch2 = ((dbus_buf[1] >> 3) | (dbus_buf[2] << 5)) & 0x07ff;
//	rc_ctrl->ch3 = ((dbus_buf[2] >> 6) | (dbus_buf[3] << 2) | (dbus_buf[4] << 10)) & 0x07ff;
//	rc_ctrl->ch4 = ((dbus_buf[4] >> 1) | (dbus_buf[5] << 7)) & 0x07ff;
//	rc_ctrl->sw_right = ((dbus_buf[5] >> 4) & 0x0003);
//	rc_ctrl->sw_left = ((dbus_buf[5] >> 4) & 0x000C) >> 2;
//	rc_ctrl->mouse.vx = dbus_buf[6] | (dbus_buf[7] << 8);
//	rc_ctrl->mouse.vy = dbus_buf[8] | (dbus_buf[9] << 8);
//	rc_ctrl->mouse.vz = dbus_buf[10] | (dbus_buf[11] << 8);
//	rc_ctrl->mouse.press_l = dbus_buf[12];
//	rc_ctrl->mouse.press_r = dbus_buf[13];
//	rc_ctrl->keyboard.key_code = dbus_buf[14] | (dbus_buf[15] << 8);
//	rc_ctrl->wheel = dbus_buf[16] | (dbus_buf[17] << 8);

//	rc_ctrl->ch1 -= 1024;
//	rc_ctrl->ch2 -= 1024;
//	rc_ctrl->ch3 -= 1024;
//	rc_ctrl->ch4 -= 1024;
//	rc_ctrl->wheel -= 1024;
//
//	if(rc_ctrl->sw_left!=sw_left_last)
//	{
//		if((sw_left_last==RC_SW_MID)&&(rc_ctrl->sw_left==RC_SW_UP)){rc_ctrl->sw_left_midtoup_flag=1;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=0;}
//		else if((sw_left_last==RC_SW_UP)&&(rc_ctrl->sw_left==RC_SW_MID)){rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=1;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=0;}
//		else if((sw_left_last==RC_SW_MID)&&(rc_ctrl->sw_left==RC_SW_DOWN)){rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=1;rc_ctrl->sw_left_downtomid_flag=0;}
//		else if((sw_left_last==RC_SW_DOWN)&&(rc_ctrl->sw_left==RC_SW_MID)){rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=1;}
//		else {rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=0;}
//	}
//	else {rc_ctrl->sw_left_midtoup_flag=0;rc_ctrl->sw_left_uptomid_flag=0;rc_ctrl->sw_left_midtodown_flag=0;rc_ctrl->sw_left_downtomid_flag=0;}
//
//	if(rc_ctrl->sw_right!=sw_right_last)
//	{
//		if((sw_right_last==RC_SW_MID)&&(rc_ctrl->sw_right==RC_SW_UP)){rc_ctrl->sw_right_midtoup_flag=1;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=0;}
//		else if((sw_right_last==RC_SW_UP)&&(rc_ctrl->sw_right==RC_SW_MID)){rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=1;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=0;}
//		else if((sw_right_last==RC_SW_MID)&&(rc_ctrl->sw_right==RC_SW_DOWN)){rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=1;rc_ctrl->sw_right_downtomid_flag=0;}
//		else if((sw_right_last==RC_SW_DOWN)&&(rc_ctrl->sw_right==RC_SW_MID)){rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=1;}
//		else {rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=0;}
//	}
//	else {rc_ctrl->sw_right_midtoup_flag=0;rc_ctrl->sw_right_uptomid_flag=0;rc_ctrl->sw_right_midtodown_flag=0;rc_ctrl->sw_right_downtomid_flag=0;}
//
//	sw_left_last = rc_ctrl->sw_left;
//	sw_right_last = rc_ctrl->sw_right;
//}

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{

	if (huart->Instance == UART5)
	{
		if (Size <= BUFF_SIZE)
		{
			HAL_UARTEx_ReceiveToIdle_DMA(&huart5, rx_buff, BUFF_SIZE * 2); // 接收完毕后重启
			sbus_frame_parse(&remoter, &rc_ctrl, rx_buff);
			//			memset(rx_buff, 0, BUFF_SIZE);
		}
		else // 接收数据长度大于BUFF_SIZE，错误处理
		{
			HAL_UARTEx_ReceiveToIdle_DMA(&huart5, rx_buff, BUFF_SIZE * 2); // 接收完毕后重启
			memset(rx_buff, 0, BUFF_SIZE);
		}
	}
}

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == UART5)
	{
		HAL_UARTEx_ReceiveToIdle_DMA(&huart5, rx_buff, BUFF_SIZE * 2); // 接收发生错误后重启
		memset(rx_buff, 0, BUFF_SIZE);								   // 清除接收缓存
	}
}

void remoteTask(void const *argument)
{
	// HAL_UARTEx_ReceiveToIdle_DMA(&huart5, rx_buff, BUFF_SIZE*2);
	while (1)
	{
		HAL_UARTEx_ReceiveToIdle_DMA(&huart5, rx_buff, BUFF_SIZE * 2);
		osDelay(10);
	}
}